from django.db import models
from datetime import timedelta
import qrcode
from io import BytesIO
from django.core.files import File
from django.contrib.auth.models import  User
from django.shortcuts import redirect, render
from django.core.files.base import ContentFile
from datetime import date


class FoodCategory(models.Model):
    CATEGORY_TYPES = (
        ('system', '系统分类'),
        ('custom', '用户自定义')
    )
    category_type = models.CharField(max_length=10, choices=CATEGORY_TYPES, default='system')
    name = models.CharField(max_length=50, verbose_name="分类名称")
    description = models.TextField(blank=True, verbose_name="分类描述")

    def __str__(self):
        return self.name
class StorageLocation(models.Model):
    class Meta:
        unique_together = [('user', 'name', 'parent')]  # 确保唯一性约束正确

    name = models.CharField(max_length=50)
    level = models.IntegerField(choices=[(1, '一级'), (2, '二级'), (3, '三级')])
    parent = models.ForeignKey('self', on_delete=models.CASCADE, 
                              null=True, blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    def __str__(self):
        return f"{self.name}（ID:{self.id}）"
    qr_code = models.ImageField(upload_to='location_qrcodes/', blank=True, verbose_name="位置二维码")
    def save(self, *args, **kwargs):
        # 自动计算层级逻辑
        if self.parent:
            self.level = self.parent.level + 1
        else:
            self.level = 1  # 默认一级分类
            
        # 先保存对象以生成id
        is_new = not self.pk
        super().save(*args, **kwargs)
        # 修复后的新创建对象判断
        if is_new or not self.qr_code:  # 新增二维码缺失判断
            self.generate_qr_code()
    def generate_qr_code(self):
        from django.core.files.base import ContentFile
        import qrcode
        from io import BytesIO
        
        content = f"location:{self.id}"
        qr = qrcode.make(content)
        buffer = BytesIO()
        qr.save(buffer, format='PNG')
        
        filename = f'location_qr_{self.id}.png'
        self.qr_code.save(
            filename,
            ContentFile(buffer.getvalue()),
            save=False
        )
        # 仅保留正确的保存方式
        super().save(update_fields=['qr_code'])
        def get_level_display(self):
            return ['一级', '二级', '三级'][self.level-1]
    # 修复缩进问题并将方法移到类作用域
    def get_full_path(self):
        """生成存储位置的完整层级路径
        通过遍历父位置构建路径字符串
        返回格式示例：'厨房 → 冷藏区 → 上层'
        """
        path = []
        current = self
        while current:
            path.insert(0, current.name)  # 逆序插入保证父级在前
            current = current.parent      # 沿父级链向上遍历
        return ' → '.join(path)           # 用箭头符号连接路径节点
     
class Food(models.Model):
    name = models.CharField(max_length=100)
    production_date = models.DateField()
    shelf_life = models.PositiveIntegerField()
    expiration_date = models.DateField()
    # location = models.ForeignKey(StorageLocation, on_delete=models.CASCADE)
    category = models.ForeignKey(FoodCategory, on_delete=models.CASCADE)
    quantity = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        default=0.00,
        verbose_name="食品数量"
    )
    unit = models.CharField(max_length=20)
    notes = models.TextField(blank=True)
    qr_code = models.ImageField(upload_to='qrcodes/')
    def save(self, *args, **kwargs):
        # 自动计算过期日期
        if self.production_date and self.shelf_life:
            self.expiration_date = self.production_date + timedelta(days=self.shelf_life)
        super().save(*args, **kwargs)
        if not self.qr_code:  
            self.generate_qr_code()
    def generate_qr_code(self):
        content = f"food:{self.id}"  # 统一标识前缀
        qr = qrcode.make(content)
        buffer = BytesIO()
        qr.save(buffer)
        filename = f'food_qr_{self.id}.png'
        self.qr_code.save(filename, File(buffer), save=False)
        super().save(update_fields=['qr_code'])
    @property
    def days_until_expiration(self):
        if self.expiration_date:
            delta = self.expiration_date - date.today()  # 直接使用日期差
            return delta.days  # 返回整数天数
        return None

    def __str__(self):
        return self.name
    category = models.ForeignKey(
        FoodCategory,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name="食品分类"
    )
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        verbose_name="所属用户"
    )
    image = models.ImageField(upload_to='food_images/', blank=True, verbose_name="食品图片")
    quantity_status = models.CharField(max_length=20, choices=[
        ('intact', '未拆封'),
        ('90%', '90%'), ('80%', '80%'), ('70%', '70%'), 
        ('60%', '60%'), ('50%', '50%'), ('40%', '40%'),
        ('30%', '30%'), ('20%', '20%'), ('10%', '10%')
    ], default='intact', verbose_name="余量状态")
    shelf_life_unit = models.CharField(max_length=10, choices=[
        ('day', '天'), ('month', '月'), ('year', '年')
    ], default='day', verbose_name="保质期单位")
    location = models.ForeignKey('StorageLocation', on_delete=models.SET_NULL, 
                                null=True, blank=True, verbose_name="存放位置")
   
def add_food(request):
    if not request.user.is_authenticated:
        return redirect('login')
    
    if request.method == 'POST':
        form = FoodForm(request.POST, request.FILES)  # 添加文件上传处理
        if form.is_valid():
            food = form.save(commit=False)
            food.user = request.user
            food.save()  # 确保调用模型的save方法
            return redirect('food_detail', food_id=food.id)  # 改为重定向
        else:
            # 添加错误处理
            print("表单错误:", form.errors)
    # 补充GET请求处理
    return render(request, 'food_management/add_food.html', {'form': form})
class ScanRecord(models.Model):
    food = models.ForeignKey(Food, on_delete=models.CASCADE)
    scan_time = models.DateTimeField(auto_now_add=True)
    device_info = models.CharField(max_length=200)

    def __str__(self):
        return f"{self.food.name} @ {self.scan_time}"